home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 8.0 KB | 300 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: SLSrtArr.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFound.hpp"
-
- #ifndef SLSRTARR_H
- #include "SLSrtArr.h"
- #endif
-
- #ifndef SLMEMMGR_H
- #include "SLMemMgr.h"
- #endif
-
- #ifndef FWPRIDEB_H
- #include "FWPriDeb.h"
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment fwcollec
- #endif
-
- //========================================================================================
- // Local constants
- //========================================================================================
-
- const long kDefaultCapacity = 16;
-
- //========================================================================================
- // FW_SPrivSortedArray
- //========================================================================================
-
- struct FW_SPrivSortedArray
- {
- void** fArray;
- long fLength;
- long fCapacity;
- FW_SortedArray_CompareFunction fCompare;
- };
-
- //========================================================================================
- // Global functions
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_New
- //----------------------------------------------------------------------------------------
-
- FW_HSortedArray FW_PrivSortedArray_New(FW_PlatformError* error, FW_SortedArray_CompareFunction compare)
- {
- // No try block necessary - Do not throw
- *error = FW_xNoError;
- FW_HSortedArray self = (FW_HSortedArray) FW_PrimitiveAllocateBlock(sizeof(FW_SPrivSortedArray));
- if (!self)
- {
- *error = FW_xMemoryExhausted;
- return NULL;
- }
- self->fArray = (void**) FW_PrimitiveAllocateBlock(sizeof(void*)*kDefaultCapacity);
- if (!self->fArray)
- {
- *error = FW_xMemoryExhausted;
- return NULL;
- }
- self->fLength = 0;
- self->fCapacity = kDefaultCapacity;
- FW_ASSERT(compare != 0);
- self->fCompare = compare;
-
- return self;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_Dispose
- //----------------------------------------------------------------------------------------
-
- void FW_PrivSortedArray_Dispose(FW_HSortedArray self)
- {
- // No try block necessary - Do not throw
- FW_PrimitiveFreeBlock(self->fArray);
- FW_PrimitiveFreeBlock(self);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_GetLength
- //----------------------------------------------------------------------------------------
-
- long FW_PrivSortedArray_GetLength(FW_HSortedArray self)
- {
- // No try block necessary - Do not throw
- return self->fLength;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_Get
- //----------------------------------------------------------------------------------------
-
- void* FW_PrivSortedArray_GetItemAt(FW_HSortedArray self, long index)
- {
- // No try block necessary - Do not throw
- FW_ASSERT(index <= self->fLength);
- return self->fArray[index];
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_Find
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_PrivSortedArray_Find(FW_HSortedArray self,
- void* item,
- long* index)
- {
- // No try block necessary - Do not throw
- FW_ASSERT(self->fLength >= 0);
- FW_ASSERT(self->fCapacity >= self->fLength);
-
- *index = 0;
- if (self->fLength == 0)
- return false;
-
- long lo = 0;
- int result = (*self->fCompare)(item, self->fArray[lo]);
- if (result < 0)
- return false;
- if (result == 0)
- return true;
-
- long high = self->fLength - 1;
- *index = high;
- result = (*self->fCompare)(item, self->fArray[high]);
- if (result == 0)
- return true;
- if (result > 0)
- {
- *index = high+1;
- return false;
- }
-
- FW_ASSERT(lo < high);
- FW_ASSERT((*self->fCompare)(item, self->fArray[lo]) > 0);
- FW_ASSERT((*self->fCompare)(item, self->fArray[high]) < 0);
-
- while (lo+1 < high)
- {
- long mid = (lo+high)/2;
- result = (*self->fCompare)(item, self->fArray[mid]);
- if (result == 0)
- {
- *index = mid;
- return true;
- }
- if (result < 0)
- {
- high = mid;
- }
- else
- {
- lo = mid;
- }
-
- FW_ASSERT((*self->fCompare)(item, self->fArray[lo]) > 0);
- FW_ASSERT((*self->fCompare)(item, self->fArray[high]) < 0);
- }
-
- // FW_ASSERT((*self->fCompare)(item, self->fArray[lo]) > 0);
- // FW_ASSERT((*self->fCompare)(item, self->fArray[lo+1]) < 0);
-
- *index = lo+1;
- return false;
- }
-
- //----------------------------------------------------------------------------------------
- // Grow
- //----------------------------------------------------------------------------------------
-
- static void Grow(FW_HSortedArray self,
- FW_PlatformError* error)
- {
- // No try block necessary - Do not throw
- *error = 0;
- long newCapacity = self->fCapacity*2;
- self->fArray = (void**) FW_PrimitiveResizeBlock(self->fArray,
- sizeof(void*)*newCapacity);
- if (self->fArray == 0)
- {
- *error = FW_xMemoryExhausted;
- return;
- }
- self->fCapacity = newCapacity;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_Insert
- //----------------------------------------------------------------------------------------
-
- void FW_PrivSortedArray_Insert(FW_HSortedArray self,
- void* newItem,
- long index,
- FW_PlatformError* error)
- {
- // No try block necessary - Do not throw
- *error = FW_xNoError;
- FW_ASSERT(self->fLength >= 0);
- FW_ASSERT(self->fCapacity >= self->fLength);
- FW_ASSERT(index >= 0);
- FW_ASSERT(index <= self->fLength);
-
- FW_ASSERT((index==self->fLength) || ((*self->fCompare)(newItem, self->fArray[index]) < 0));
- FW_ASSERT((index==0) || ((*self->fCompare)(newItem, self->fArray[index-1]) > 0));
-
- if (self->fLength == self->fCapacity)
- {
- Grow(self, error);
- if (*error != FW_xNoError)
- return;
- }
-
- FW_PrimitiveCopyMemory(self->fArray + index,
- self->fArray + index + 1,
- (self->fLength - index) * sizeof(void*));
-
- self->fArray[index] = newItem;
- ++self->fLength;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_Add
- //----------------------------------------------------------------------------------------
-
- void FW_PrivSortedArray_Add(FW_HSortedArray self,
- void* newItem,
- long* index,
- FW_PlatformError* error)
- {
- // No try block necessary - Do not throw
- *error = FW_xNoError;
- FW_Boolean result = FW_PrivSortedArray_Find(self, newItem, index);
- FW_ASSERT(!result);
- if (result)
- {
- *error = FW_xBadInsert;
- return;
- }
- FW_PrivSortedArray_Insert(self, newItem, *index, error);
- return;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_RemoveIndex
- //----------------------------------------------------------------------------------------
-
- void FW_PrivSortedArray_RemoveIndex(FW_HSortedArray self,
- long index,
- FW_PlatformError* error)
- {
- // No try block necessary - Do not throw
- *error = FW_xNoError;
- if (index > (self->fLength - 1))
- {
- *error = FW_xBadRemove;
- return;
- }
-
- --self->fLength;
-
- if (index < self->fLength)
- {
- FW_PrimitiveCopyMemory(self->fArray + index + 1,
- self->fArray + index,
- (self->fLength - index) * sizeof(void*));
-
- }
- return;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_PrivSortedArray_RemoveItem
- //----------------------------------------------------------------------------------------
-
- void FW_PrivSortedArray_RemoveItem(FW_HSortedArray self,
- void* item,
- FW_PlatformError* error)
- {
- *error = FW_xNoError;
- long index;
- FW_Boolean result = FW_PrivSortedArray_Find(self, item, &index);
- FW_ASSERT(result);
- if (!result)
- {
- *error = FW_xBadRemove;
- return;
- }
- FW_PrivSortedArray_RemoveIndex(self, index, error);
- return;
- }